package com.example.normal.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.example.utils.Consts;
import com.example.base.domain.PageVo;
import com.example.base.result.AjaxResult;
import com.example.normal.entity.Student;
import com.example.normal.service.IStudentService;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * @author wahoyu
 * @since 2023-07-23
 */
@RestController
@Slf4j
@RequestMapping("/student")
public class StudentController {

    @Resource
    IStudentService studentService;

    /**
     * 分页查询列表
     * @author wanghongyu02
     * @date 2024-07-25 17:24
     * @param student
     * @param pageVo
     * @return com.example.base.result.AjaxResult
     */
    @PostMapping("/list")
    public AjaxResult list(@RequestBody Student student, PageVo pageVo) {
        return AjaxResult.success(studentService.selectVoList(student, pageVo));
    }

    /**
     * 根据Id查询单条数据
     * @author wanghongyu02
     * @date 2024-07-25 17:24
     * @param id
     * @return com.example.base.result.AjaxResult
     */
    @GetMapping("/{id}")
    public AjaxResult getInfo(@PathVariable BigInteger id) {
        return AjaxResult.success(studentService.getById(id));
    }

    /**
     * 修改
     * @author wanghongyu02
     * @date 2024-07-25 17:25
     * @param student
     * @return com.example.base.result.AjaxResult
     */
    @PostMapping("/update")
    public AjaxResult update(@RequestBody Student student) {
        //设置必要参数
        student.setUpdateTime(new Date());
        student.setUpdateBy("未知");
        //逻辑删除字段
        student.setDeleteFlag(Consts.DELETE_FLAG.IN_USE);
        return AjaxResult.success(studentService.updateById(student));
    }

    /**
     * 可置空-修改
     * @author wanghongyu02
     * @date 2024-07-25 17:25
     * @param student
     * @return com.example.base.result.AjaxResult
     */
    @PostMapping("/updateWithNull")
    public AjaxResult updateWithNull(@RequestBody Student student) {
        return AjaxResult.success(studentService.updateWithNull(student));
    }


    /**
     * 删除
     * @author wanghongyu02
     * @date 2024-07-25 17:25
     * @param id
     * @return com.example.base.result.AjaxResult
     */
    @DeleteMapping("/{id}")
    public AjaxResult remove(@PathVariable BigInteger id) {
        return AjaxResult.success(studentService.deleteById(id));
    }

    /**
     * 添加
     * @author wanghongyu02
     * @date 2024-07-25 17:25
     * @param student
     * @return com.example.base.result.AjaxResult
     */
    @PostMapping("/add")
    public AjaxResult add(@RequestBody Student student) {
        studentService.insert(student);
        return AjaxResult.success();
    }

    /**
     * 批量导出Excel
     * @author wanghongyu02
     * @date 2024-07-19 17:04
     * @param fileName
     * @param response
     * @return
     */
    @PostMapping(value = "/export/student")
    public void exportData(String fileName, HttpServletResponse response) {
        try {

            this.setExcelResponseProp(response, fileName);

            //通过业务代码获取数据
            List<Student> studentList = studentService.list();

            //写数据并通过response返回
            EasyExcelFactory.write(response.getOutputStream())
                    .head(Student.class) //表头
                    .excelType(ExcelTypeEnum.XLSX) //设置导出Excel文件的后缀
                    .sheet(fileName) //设置工作表sheet名称
                    .doWrite(studentList);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Excel导入
     * @author wanghongyu02
     * @date 2024-07-24 16:22
     * @param file
     * @return com.example.base.result.AjaxResult
     */
    @PostMapping("/import/student")
    public AjaxResult importUserExcel(@RequestPart(value = "file") MultipartFile file) {
        try {
            List<Student> userList = EasyExcel.read(file.getInputStream())
                    .head(Student.class)
                    .sheet()
                    .doReadSync();

            //插入操作
            userList.forEach(student -> studentService.insert(student));

            return AjaxResult.success(userList);
        } catch (IOException e) {
            return AjaxResult.error();
        }
    }

    /**
     * 设置响应结果
     * @author wanghongyu02
     * @param response 响应结果对象
     * @param rawFileName 文件名
     * @throws UnsupportedEncodingException 不支持编码异常
     */
    private void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    }

    /**
     * 测试当前数据源名称
     * @author wanghongyu02
     * @date 2024-08-13 15:07
     */
    @GetMapping("/dataSourceName")
    public void dataSourceName() {

        //查询手动推栈的数据源名称
        DynamicDataSourceContextHolder.push("master");
        log.info("dataSourceName1:{}", DynamicDataSourceContextHolder.peek()); // master
        DynamicDataSourceContextHolder.clear();
        log.info("dataSourceName22:{}", DynamicDataSourceContextHolder.peek()); // null
    }

    /**
     * 测试wrapper与实体类参数
     * @author wanghongyu02
     */
    @PostMapping("/testWrapper")
    public AjaxResult testWrapper() {
        List<Student> list = studentService.testWrapper();
        return AjaxResult.success(list);
    }

}

